home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #3 / Amiga Plus CD - 2002 - No. 03.iso / AmiSoft / Dev / C / Tinygl.lha / TinyGL / src / gla.c < prev    next >
Encoding:
C/C++ Source or Header  |  2003-01-22  |  8.7 KB  |  333 lines

  1.  
  2. #include <GL/gla.h>
  3. #include "zgl.h"
  4.  
  5. static unsigned long *recup_cmap(int nc, unsigned long *cr);
  6.  
  7. typedef struct {
  8.     GLContext *gl_context;
  9.     int xsize,ysize;
  10.  
  11.     GLADrawable drawable;
  12.     unsigned char *image;
  13.     int bpp;
  14.  
  15.     int do_convert;
  16.     struct BitMap *bitmap;
  17. } TinyGLAContext;
  18.  
  19.  
  20. /*
  21.  * CreateContext
  22.  */
  23. GLAContext glACreateContext(void) //Display *dpy, XVisualInfo *vis, GLAContext shareList, BOOL direct )
  24. {
  25.   TinyGLAContext *ctx;
  26.  
  27.   ctx=gl_malloc(sizeof(TinyGLAContext));
  28.     if (!ctx){
  29.         return NULL;
  30.     }
  31.   ctx->gl_context=NULL;
  32.     ctx->image=NULL;
  33.     ctx->bitmap = NULL;
  34.     ctx->drawable=NULL;
  35.  
  36.   return (GLAContext) ctx;
  37. }
  38.  
  39.  
  40. /*
  41.  * DestroyContext
  42.  */
  43. void glADestroyContext(GLAContext ctx1)
  44. {
  45.     TinyGLAContext *ctx = (TinyGLAContext *) ctx1;
  46.     
  47.     // Close zbuffer and other things if necessary (dither stuff, frame buffer
  48.     // if internally allocated, ...)
  49.   ZB_close(ctx->gl_context->zb);
  50.     
  51.   // Destroy the internal GLContext struct
  52.   if (ctx->gl_context != NULL) {
  53.     glClose();
  54.   }
  55.     
  56.     // Display buffers to be freed
  57.     if (ctx->image){
  58.     gl_free(ctx->image);
  59.     } 
  60.     if (ctx->bitmap){
  61.     FreeBitMap(ctx->bitmap);
  62.     }
  63.  
  64.   gl_free(ctx);
  65. }
  66.  
  67. /* resize the glx viewport : we try to use the xsize and ysize
  68. given. We return the effective size which is guaranted to be smaller */
  69.  
  70. static int glA_resize_viewport(GLContext *c, int *xsize_ptr, int *ysize_ptr)
  71. {
  72.     TinyGLAContext *ctx;
  73.     int xsize,ysize;
  74.         
  75.     ctx=(TinyGLAContext *)c->opaque;
  76.  
  77.     xsize=*xsize_ptr;
  78.     ysize=*ysize_ptr;
  79.  
  80.     /* we ensure that xsize and ysize are multiples of 2 for the zbuffer.
  81. TODO: find a better solution */
  82.     xsize&=~3;
  83.     ysize&=~3;
  84.  
  85.     if (xsize == 0 || ysize == 0) return -1;
  86.  
  87.     *xsize_ptr=xsize;
  88.     *ysize_ptr=ysize;
  89.     
  90.     if (ctx->bpp == 8){
  91.         if (ctx->image == NULL){
  92.             ctx->image = (unsigned char *)gl_malloc(xsize * ysize * (ctx->bpp / 8));
  93.         }else{
  94.             if ((xsize !=   ctx->xsize) || (ysize != ctx->ysize)){
  95.                 gl_free(ctx->image);
  96.                 ctx->image = (unsigned char *)gl_malloc(xsize * ysize * (ctx->bpp / 8));
  97.             }
  98.         }
  99.         if (ctx->image == NULL){
  100.             return -1;
  101.         }
  102.     }else{
  103.         if (ctx->bitmap == NULL){
  104.             ctx->bitmap = AllocBitMap(xsize, ysize, 16, BMF_MINPLANES|BMF_SPECIALFMT|SHIFT_PIXFMT(PIXFMT_RGB16), NULL); //ctx->drawable->RPort->BitMap);
  105.         }else{
  106.             if ((xsize !=   ctx->xsize) || (ysize != ctx->ysize)){
  107.                 FreeBitMap(ctx->bitmap);
  108.                 ctx->bitmap = AllocBitMap(xsize, ysize, 16, BMF_MINPLANES|BMF_SPECIALFMT|SHIFT_PIXFMT(PIXFMT_RGB16), NULL); //ctx->drawable->RPort->BitMap);
  109.             }
  110.         }
  111.         if (ctx->bitmap == NULL){
  112.             return -1;
  113.         }
  114.     }
  115.     ctx->xsize=xsize;
  116.     ctx->ysize=ysize;
  117.     
  118.     /* resize the Z buffer */
  119.     //if (ctx->do_convert){
  120.       ZB_resize(c->zb,NULL,xsize,ysize);
  121.     //}else{
  122.     //  ZB_resize(c->zb,ctx->image,xsize,ysize);
  123.     //}
  124.  
  125.     return 0;
  126. }
  127.  
  128. /*
  129.  * MakeCurrent
  130.  */
  131. /* we assume here that drawable is a window */
  132. int glAMakeCurrent(GLADrawable drawable, GLAContext ctx1)
  133. {
  134.   TinyGLAContext *ctx = (TinyGLAContext *) ctx1;
  135.   int xsize,ysize;
  136.   ZBuffer *zb;
  137.   unsigned int palette[ZB_NB_COLORS];
  138.   unsigned char color_indexes[ZB_NB_COLORS];
  139.     unsigned long *new_palette;
  140.     int i;
  141.     int mode;
  142.     int bpp;
  143.     struct Screen *currentScreen;
  144.    
  145.     //if((dpy==NULL)||(ctx1==NULL)) return(0);
  146.  
  147.     bpp = GetBitMapAttr(drawable->RPort->BitMap, BMA_DEPTH);
  148.  
  149. /*
  150.     if (bpp >= 15){
  151.         bpp = 24;
  152.     }
  153. */
  154.     ctx->bpp = bpp;
  155.    
  156.   if (ctx->gl_context == NULL) {
  157.  
  158.     /* create the TinyGL context */
  159.  
  160.         ctx->drawable=drawable;
  161.      
  162.         xsize = drawable->Width;
  163.         ysize = drawable->Height;
  164.  
  165.         switch (bpp){
  166.                     case 8:
  167.                         mode = ZB_MODE_INDEX;
  168.                         
  169.                         for(i=0;i<ZB_NB_COLORS;i++){
  170.                             color_indexes[i]=i;
  171.                         }
  172.  
  173.                         /* Open the Z Buffer - 256 colors */
  174.                         zb=ZB_open(xsize,ysize,mode,ZB_NB_COLORS,color_indexes,palette,NULL);
  175.                         if (zb == NULL) {
  176.                             fprintf(stderr, "Error while initializing Z buffer\n");
  177.                             exit(1);
  178.                         }
  179.  
  180.                         // Affectation de la cmap au drawable si l'écran n'est pas le Wb
  181.                         currentScreen = LockPubScreen("Workbench");
  182.                         if (currentScreen){
  183.                             if (currentScreen != drawable->WScreen){
  184.                                 new_palette = recup_cmap(ZB_NB_COLORS, (unsigned long *)palette);
  185.                                 LoadRGB32(&drawable->WScreen->ViewPort, new_palette);
  186.                                 free(new_palette);
  187.                                 UnlockPubScreen(NULL, currentScreen);
  188.                             }
  189.                         }
  190.  
  191.             ctx->do_convert = 1;
  192.             break;
  193. /*
  194.                     case 24:
  195.             mode = ZB_MODE_RGB24;
  196.             ctx->do_convert = 1; //TGL_FEATURE_RENDER_BITS != 16;
  197.             zb = ZB_open(xsize, ysize, mode, 0, NULL, NULL, NULL);
  198.             break;
  199.                     case 32:
  200.             mode = ZB_MODE_RGBA;
  201.             ctx->do_convert = 1; //TGL_FEATURE_RENDER_BITS != 16;
  202.             zb = ZB_open(xsize, ysize, mode, 0, NULL, NULL, NULL); //ctx->image);
  203.             break;
  204. */
  205.  
  206.                     default:
  207.                   mode = ZB_MODE_5R6G5B;
  208.                         zb = ZB_open(xsize, ysize, mode, 0, NULL, NULL, NULL);
  209.         }
  210.             
  211.             if (zb == NULL){
  212.                 fprintf(stderr,    "Error while initializing Z buffer\n");
  213.                 exit(1);
  214.             }
  215.  
  216.  
  217.     /* initialisation of the TinyGL interpreter */
  218.     glInit(zb);
  219.  
  220.     ctx->gl_context=gl_get_context();
  221.     ctx->gl_context->opaque=(void *) ctx;
  222.         ctx->gl_context->gl_resize_viewport=glA_resize_viewport;
  223.  
  224.     /* set the viewport : we force a call to glX_resize_viewport */
  225.     ctx->gl_context->viewport.xsize=-1;
  226.     ctx->gl_context->viewport.ysize=-1;
  227.  
  228.         glViewport(0, 0, xsize, ysize);
  229.   }
  230.  
  231.   return 1;
  232. }
  233.  
  234.  
  235. /*
  236.  * SwapBuffers
  237.  */
  238. void glASwapBuffers(GLADrawable drawable)
  239. {
  240.   GLContext *gl_context;
  241.   TinyGLAContext *ctx;
  242.     int i;
  243.     int comp = 0;
  244.     unsigned char *ptr;
  245.     //unsigned long *new_palette;
  246.     unsigned short *seize;
  247.     unsigned short s;
  248.     unsigned char *buf;
  249.     unsigned char r,g,b;
  250.     APTR bmapHandle;
  251.     ULONG bmapBase;
  252.         
  253.   /* retrieve the current GLXContext */
  254.   gl_context=gl_get_context();
  255.   ctx=(TinyGLAContext *)gl_context->opaque;
  256.  
  257.     if (ctx->bpp == 8){
  258.         ZB_copyFrameBuffer(ctx->gl_context->zb, ctx->image, ctx->xsize);
  259.         
  260.         WriteChunkyPixels(drawable->RPort, 0, 0, drawable->Width - 1, drawable->Height - 1, (unsigned char *)ctx->image/*ctx->gl_context->zb->pbuf*/, drawable->Width);
  261.     }else{
  262. /*
  263.         if (ctx->do_convert){
  264.           // bytes per line en dernier argument
  265.           ZB_copyFrameBuffer(ctx->gl_context->zb, ctx->image, ctx->xsize * ctx->bpp / 8);
  266.         }
  267.  
  268.         switch (ctx->bpp){
  269.             case 32:
  270.                 (void)WritePixelArray(ctx->image,
  271.                                                 0,0,
  272.                                                 drawable->Width * ctx->bpp / 8,
  273.                                                 drawable->RPort,
  274.                                                 0, 0,
  275.                                                 drawable->Width,
  276.                                                 drawable->Height,
  277.                                                 RECTFMT_ARGB);
  278.                 break;
  279.  
  280.             default:
  281.                 (void)WritePixelArray(ctx->image,
  282.                                                 0,0,
  283.                                                 drawable->Width * ctx->bpp / 8,
  284.                                                 drawable->RPort,
  285.                                                 0, 0,
  286.                                                 drawable->Width,
  287.                                                 drawable->Height,
  288.                                                 RECTFMT_RGB);
  289.         }
  290. */
  291.  
  292.  
  293.         bmapHandle = LockBitMapTags(ctx->bitmap, LBMI_BASEADDRESS, &bmapBase, TAG_DONE);
  294.         if (bmapHandle){
  295.             //ZB_copyBuffer(ctx->gl_context->zb, bmapBase, ctx->xsize * 2);
  296.             CopyMemQuick(ctx->gl_context->zb->pbuf, bmapBase, ctx->xsize * ctx->ysize * 2);
  297.             UnLockBitMap(bmapHandle);
  298.         }
  299.  
  300.         BltBitMapRastPort(ctx->bitmap, 0, 0, drawable->RPort, drawable->BorderLeft, drawable->BorderTop, ctx->xsize * 2, ctx->ysize, 0xc0);
  301.  
  302.     }
  303. }
  304.  
  305. /* Create an AmigaOS color map (usable with LoadRGB32()) */
  306. static unsigned long *recup_cmap(int nc, unsigned long *cr)
  307. {
  308.     int c;
  309.     unsigned long *colourtable;
  310.     unsigned char r, g, b;
  311.  
  312.     if ((colourtable = (unsigned long *)malloc((1 + 3 * nc + 1) * sizeof(unsigned long))))
  313.     {
  314.         colourtable[0] = (nc << 16) + 0;
  315.  
  316.         for (c = 0; c < nc; c++)
  317.         {
  318.             r = (unsigned char)((cr[c]>>16) & 0xFF);
  319.             g = (unsigned char)((cr[c]>>8) & 0xFF);
  320.             b = (unsigned char)((cr[c]) & 0xFF);
  321.        
  322.             colourtable[3 * c + 1] = (unsigned long)(r * 0x01010101);
  323.             colourtable[3 * c + 2] = (unsigned long)(g * 0x01010101);
  324.             colourtable[3 * c + 3] = (unsigned long)(b * 0x01010101);
  325.         }
  326.  
  327.         colourtable[1 + 3 * nc] = 0;
  328.     }
  329.  
  330.     return colourtable;
  331. }
  332.  
  333.